#!/usr/bin/python
"""vmc server  for Python

Usage: python vmc_server.py [--daemon] ip [port]
    ip use specified server binding address
Options:
    --daemon -- start as a daemon
    port     -- use specified server binding port (default 8989)
Examples:
python vmc_server.py 127.0.0.1
python vmc_server.py --daemon 192.168.4.120 10000

"""
import re
import libvirt
import sys
import os
import urllib,socket
import tarfile
import commands
import time
import datetime
import signal
import ConfigParser
import thread
import string
import tempfile
from xml.dom import minidom

from ivic.core import Config
from ivic.core import Logging
from ivic.core.Utils import close_all
from ivic.vmc.Error import *
from ivic.vmc.Domain import *
from ivic.vmc.Configure import *
from ivic.vmc.Network import NetworkXml
from ivic.vmc.Nfs_Action import *
from ivic.vmc.Pcap import *
from ivic.vmc.DomainParse import *
from ivic.vmc.Vnode import *
from ivic.vmc.NetworkParse import *
from ivic.vmc.MemImage import *

Null = None

def exe_command(command):
    pipe=os.popen(command,"r")
    result=pipe.readlines()
    pipe.close()
    return result
def lookup_nbd_device():
	nbd_device_prefix="/dev/nbd";
	for i in range(16):
		nbd_device = nbd_device_prefix + str(i);
		if not os.path.exists(nbd_device+"p1"):
			return nbd_device;
	return "/dev/nbd12";
#vnet_pid_map = {}
#vnet_tap_map = {}

VSWITCH= "/switch"
lock = thread.allocate_lock()
startVS_lock = thread.allocate_lock()
nbd_lock = thread.allocate_lock();
logger = Logging.get_logger('ivic.vmc.Server')

# modify VM's internal network information
def modifyVMInterfaces(xml, path, linuxType):
    try:
        workPath=os.getcwd()
        linuxType = linuxType.strip()
        xmldoc = minidom.parseString(xml)
        nics = xmldoc.getElementsByTagName("NIC")
        for i in range(len(nics)):	    
            id =  nics[i].attributes["id"].value
            address = nics[i].getElementsByTagName("Address")[0].firstChild.data
            netmask = nics[i].getElementsByTagName("Netmask")[0].firstChild.data        
            try:
                gateway = nics[i].getElementsByTagName("Gateway")[0].firstChild.data        
            except:
                gateway = None			
            
            #modify_command=""+workPath+"/modifyNetwork.sh -w "+path+" -p static -t "+linuxType+" -i "+address+" -m "+netmask+" -d eth"+id+" "
            modify_command="modifyNetwork.sh -w "+path+" -p static -t "+linuxType+" -i "+address+" -m "+netmask+" -d eth"+id+" "
            command_suffix=""

            if gateway != None:
                command_suffix+=" -g "+gateway+ " "

            if i!=0:
                command_suffix+=" -a "

            modify_command += command_suffix
            #os.system(modify_command)                       
            commands.getstatusoutput(modify_command)
    except Exception,e:
        return -2;
    return 0;    
        
#modify VM's hostname
def modifyVMHostname(hostname, path, linuxType):
    commands.getstatusoutput("modifyHostname.sh "+linuxType.strip()+" "+hostname.strip()+" "+path)
    return 0  


#******************************************************************************************************#  
def extractRootfs(tar_file_name,output_path):
    """  extract rootfs's tar.gz file   """    
    try:
        tar = tarfile.open(tar_file_name)
        tar.extractall(path=output_path)
        tar.close()
        return output_path;
    except Exception,e:
        logger.error("exception happen when unzip VM rootfs.")
        return None;
    
#******************************************************************************************************#  

#******************************************************************************************************#  

def downloadRootfs(rootfs_url,output_path):
    try:
        filename = rootfs_url.split("/")[-1]
        #if rootfs exists, don't download again
        if os.path.isfile(output_path+"/"+filename):
            rootfs_abspath = output_path+"/"+filename
            logger.info(rootfs_abspath)
            return rootfs_abspath
        #rootfs not exists
        if not os.path.exists(output_path):
            os.system("mkdir -p "+output_path)
        logger.info("wget " + rootfs_url + " -P " + output_path)
        if commands.getstatusoutput("wget " + rootfs_url + " -P " + output_path)[0] != 0:
            return Null;   
        #return absolute path of new rootfs
        rootfs_abspath = output_path+"/"+filename
        return rootfs_abspath
    except Exception, e:
        logger.error("download rootfs error.")
        return Null;        
#***********************************************************************************************************#


#***********************************************************************************************************#
def getAllBasicInfo(xml):
    '''  extract VM basic infomation from xml description '''
    try:
        xmldoc = minidom.parseString(xml)
        ref = xmldoc.getElementsByTagName("vTemplateRef")[0].firstChild.data
        hostname = xmldoc.getElementsByTagName("Hostname")[0].firstChild.data
        memory = xmldoc.getElementsByTagName("Mem")[0].firstChild.data
       
        diskSize = xmldoc.getElementsByTagName("DiskSize")[0].firstChild.data
        passwd = xmldoc.getElementsByTagName("Password")[0].firstChild.data
        return ref,hostname,memory,diskSize,passwd
    except Exception,e:
        logger.error("get all basic info from vm template, happen exception")
        return Null
#***********************************************************************************************************#


#***********************************************************************************************************#
def getAllNetworkSource(xml):
    '''   get networks information from vnode xml description
          the VM's xml description are defined by ourselves
    '''
    networkSources = []
    try:
        xmldoc = minidom.parseString(xml)
        nics = xmldoc.getElementsByTagName("NIC")
        for i in range(len(nics)):
            uuid = nics[i].getElementsByTagName("vSwitchRef")[0].firstChild.data;
            id =  nics[i].attributes["id"].value
            networkSources.append(uuid)            
        return networkSources
    except Exception,e:
        logger.error("get all network source happen exception")
        return Null
#***********************************************************************************************************#


#add by libo
# get networks information from VM libvirt xml
# return value: networks list which represents the networks that the VM are connecting to 

def getNetworkFromDomain(xml):
    networkSources = []    
    try:
        xmldoc = minidom.parseString(xml)
        interfaces = xmldoc.getElementsByTagName("interface")        

        for i in range(len(interfaces)):
            uuid = interfaces[i].getElementsByTagName("source")[0].attributes["network"].value            
            networkSources.append(uuid)

        return networkSources
    except Exception, e:
        logger.error("get all interfaces happen exception")
        return Null
        


#***************************************************************************************************************#
def getDeployInfoFromVMT(url):
    """  get vm deploy infomation from vnode xml  """
    try:
        fsock = urllib.urlopen(url)
        xmldoc =minidom.parse(fsock)
        
        vcpu = "1"
        if len(xmldoc.getElementsByTagName("vCPU")) > 0 and xmldoc.getElementsByTagName("vCPU")[0].firstChild.data != None:
            vcpu = xmldoc.getElementsByTagName("vCPU")[0].firstChild.data
            
        deployInfo = xmldoc.getElementsByTagName("DeployInfo")[0]
        method = deployInfo.getElementsByTagName("Method")[0].firstChild.data
        url = deployInfo.getElementsByTagName("URL")[0].firstChild.data
        cowdir = deployInfo.getElementsByTagName("COWDir")[0].firstChild.data
        linuxType = xmldoc.getElementsByTagName("Distribution")[0].firstChild.data;
        url=url.strip();
        method=method.strip()
        linuxType=linuxType.strip()
        fsock.close()
        return url,method,linuxType,cowdir,vcpu
    except Exception,e:
        logger.error("get deploy info, happen exception:"+str(e))
        return None,None,None,None,None
#***************************************************************************************************************#


#***************************************************************************************************************#
def getNameFromDomainXML(fname):
    """read vm's name and xmldesc from a libvirt domain's configure xml file"""
    try:
        xmldoc = minidom.parse(fname)
        ref = xmldoc.getElementsByTagName("name")[0]
        name = ref.firstChild.data
        xmldesc = xmldoc.toxml()   
        #logger.info(name+"@@"+xmldesc+"@@@") 
        return (name, xmldesc)
    except Exception,e:
        logger.error("happen exception when read domain")
        return Null

def getImagePathFromDomainXML(fname):
    """read image path from libvirt xml"""
    try:
        xmldoc = minidom.parse(fname)
        ref = xmldoc.getElementsByTagName("disk")[0]
        source = ref.getElementsByTagName("source")[0]
        image_path = source.getAttribute("file")
        return image_path
    except Exception,e:
        logger.error("Failed to get image path from libvirt  xml file:"+str(e))
        return ""
#***************************************************************************************************************#


#***************************************************************************************************************#
def getCdromURLFromURL(url):
    """get cdrom url from vnode xml"""
    try:
        fsock = urllib.urlopen(url)
        xmldoc = minidom.parse(fsock)
        ref = xmldoc.getElementsByTagName("DeployInfo")[0]
        cdrom_url = ref.getElementsByTagName("Cdrom")[0].firstChild.data;
        cdrom_url = cdrom_url.strip();
        return cdrom_url
    except Exception,e:
        logger.info("Failed to get cdrom url from vnode xml file:"+str(e))
        return ""


#***************************************************************************************************************#
        

#***************************************************************************************************************#
def saveXml2File(xml,path,filename):
    '''write xml information to a file'''
    try:
        if not os.path.exists(path):
            os.mkdir(path)
        file = open(filename,"w")
        file.write(xml)
        file.close()
    except OSError,e:
        logger.error("create file or make directory error")
        file.close()
        return -1
    except IOError,e:
        logger.error("create file or make directory error")
        file.close()
        return -2
    return 0
#***************************************************************************************************************#

#*****************************************************************************************#
def createVMImage(osType,rootfsFileName,vmImagePath,hostname,diskSize,xml,uuid=""):
    try:
         osType = osType.strip()
         if osType == "windows-xp":
             #dns = "202.112.128.51"
             #create windows images
             dns = ""
             xmldoc = minidom.parseString(xml)
             nics = xmldoc.getElementsByTagName("NIC")
             id =  nics[0].attributes["id"].value
             address = nics[0].getElementsByTagName("Address")[0].firstChild.data
             netmask = nics[0].getElementsByTagName("Netmask")[0].firstChild.data
             try:
                 gateway = nics[0].getElementsByTagName("Gateway")[0].firstChild.data
             except:
                 gateway = "0"
             try:
                 dns = self.dns
             except:
                 nameserverline = exe_command("cat /etc/resolv.conf | grep -m 1 'nameserver'")
                 dns = nameserverline[0].split()[1];
             network_info=""+address+":"+netmask+":"+gateway+":"+dns
 
             createKvmImageShell="windows_deploy.sh "+rootfsFileName+" "+vmImagePath+"/"+hostname+".img "+diskSize + " " + hostname + " "+network_info

             if commands.getstatusoutput(createKvmImageShell)[0]%256 != 0:
                 return None;
             vm_image_absFileName = vmImagePath+"/"+hostname+".img"
             return vm_image_absFileName
         else:                  
             #need tar file
             extract_rootfs_output_path = vmImagePath+"/fs"
             if not os.path.exists(extract_rootfs_output_path):
                 os.system("mkdir -p "+extract_rootfs_output_path)

             extract_rootfs_output_path = extractRootfs(rootfsFileName,extract_rootfs_output_path)
             if extract_rootfs_output_path == None:
                   #logging some message
                   return None
             vmImagePath = vmImagePath+"/"+hostname
             createKvmImageShell = "create_kvm_image.sh "+extract_rootfs_output_path+" "+vmImagePath+" "+diskSize+" "+osType+" "+uuid
             #print createKvmImageShell
             modifyVMHostname(hostname,extract_rootfs_output_path,osType)
             modifyVMInterfaces(xml,extract_rootfs_output_path,osType)	
  	     
             os.system("sed -i \"s/^exit 0/setterm -blank 0 -powerdown 0\\nexit 0/\" " +  extract_rootfs_output_path +  "/etc/rc.local")
             #os.system("sed -i -e \"s/^\(BLANK_TIME\)=.*/\\1=0/\" -e \"s/^\(POWERDOWN_TIME\)=.*/\\1=0/\" " + extract_rootfs_output_path + "/etc/console-tools/config")             
	
             sysctl = open(extract_rootfs_output_path+"/etc/sysctl.conf", "a")
             sysctl.write("\nnet.ipv4.ip_forward=1\n")
             sysctl.close()

	     #add by libo
             #os.system(createKvmImageShell)
             if commands.getstatusoutput(createKvmImageShell)[0] != 0:
                 return None
             os.system("rm -R " + extract_rootfs_output_path)
             vm_image_absFileName = vmImagePath+".img"
             return vm_image_absFileName
    except Exception, e:
             #logging error message
             logger.error("error when creating VM image")
             sys.stdout.flush()
             return Null

#*****************************************************************************************#
def mount_boot_patitiion(loop_dev, image_file, mount_dest):
        '''
        mount the boot partition of the vm image, thus we can modify the image
        '''
        logger.info('mounting boot partition ...')
        bootable_loop_dev_partition = loop_dev + 'p1'
        bootable_partition_info = commands.getstatusoutput('fdisk -l ' + loop_dev + ' | grep ' + bootable_loop_dev_partition)
        bootable_partition_system = bootable_partition_info[1].split()[-1]
        if bootable_partition_system == "HPFS/NTFS":
            mount_command = 'mount -t ntfs-3g ' + bootable_loop_dev_partition + ' ' + mount_dest
        else:
            mount_command = 'mount ' + bootable_loop_dev_partition + ' ' + mount_dest
        ret = commands.getstatusoutput(mount_command)
        time.sleep(1)
        logger.info(ret)
        if(ret[0]!=0 and bootable_partition_system == "HPFS/NTFS"):
            logger.info("We need to fix the ntfs partition")
            logger.info(commands.getstatusoutput('ntfsfix ' + bootable_loop_dev_partition))
            time.sleep(1)
            ret = commands.getstatusoutput(mount_command)
        if (ret[0] != 0):
            logger.error("Failed to mount qcow file")
            logger.info(commands.getstatusoutput('kvm-nbd --disconnect '+loop_dev)[1])
            time.sleep(1)
            return Null
        logger.info('successfully mounted ' + bootable_loop_dev_partition)
        return ret

def modify_nfsmount_image(osType,image_file,hostname,diskSize,xml,_portal, uuid="",webfarm_nodes=None):
    try:
        portal = _portal;
        portal = portal.replace("https","http")
        osType = osType.strip()
        temp_path = tempfile.mkdtemp()
        logger.debug(temp_path)
        loop_dev = lookup_nbd_device();
        #commands.getstatusoutput('kvm-nbd --disconnect '+loop_dev)
        logger.info('kvm-nbd --connect='+loop_dev+' '+image_file)
        logger.info(commands.getstatusoutput('kvm-nbd --connect='+loop_dev+' '+image_file))
        time.sleep(2)
        ret = mount_boot_patitiion(loop_dev, image_file, temp_path)
        time.sleep(1)
        logger.info(ret)
        if(ret[0]!=0):
            time.sleep(1)
            return Null
        if osType == "windows-xp":
            xmldoc = minidom.parseString(xml)
            nics = xmldoc.getElementsByTagName("NIC")
            id =  nics[0].attributes["id"].value
            address = nics[0].getElementsByTagName("Address")[0].firstChild.data
            netmask = nics[0].getElementsByTagName("Netmask")[0].firstChild.data
            try:
                gateway = nics[0].getElementsByTagName("Gateway")[0].firstChild.data
            except:
                gateway = "0"
            try:
                dnsserver = self.dns
            except:
                nameserverline = exe_command("cat /etc/resolv.conf | grep -m 1 'nameserver'")
                dnsserver = nameserverline[0].split()[1];
            network_info=""+address+":"+netmask+":"+gateway
            xpExecShellFileName=temp_path+"/NetworkConfig.bat"
            logger.info(xpExecShellFileName)
            r = create_windows_xp_interface(temp_path+"/interfaces.txt",address,netmask,gateway,dnsserver);
            logger.info(r);
            r = create_exce_shell(xpExecShellFileName,hostname);
            commands.getstatusoutput("echo uuid: "+uuid+" >"+temp_path+"/ivic/vm.yaml")
            commands.getstatusoutput("echo portal: "+portal+" >>"+temp_path+"/ivic/vm.yaml")

            logger.info(r)
            logger.info("end")
        else:
            modifyVMHostname(hostname,temp_path,osType)
            modifyVMInterfaces(xml,temp_path,osType)
            #write uuid to /etc/ivic/vm.yaml
            commands.getstatusoutput("mkdir -p "+temp_path+"/etc/ivic/")
            commands.getstatusoutput("touch "+temp_path+"/etc/ivic/vm.yaml")
            commands.getstatusoutput("echo uuid: "+uuid+" >"+temp_path+"/etc/ivic/vm.yaml")
            commands.getstatusoutput("echo portal: "+portal+" >>"+temp_path+"/etc/ivic/vm.yaml")
            xmldoc = minidom.parseString(xml)
            nics = xmldoc.getElementsByTagName("NIC")
            try:
                dnsserver = self.dns
            except:
                nameserverline = exe_command("cat /etc/resolv.conf | grep -m 1 'nameserver'")
                dnsserver = nameserverline[0].split()[1];
            commands.getstatusoutput("echo nameserver  "+dnsserver+" >"+temp_path+"/etc/resolv.conf")
            if (webfarm_nodes != None):
                commands.getstatusoutput("touch "+temp_path+"/etc/ivic/nodes.yaml")
                commands.getstatusoutput("echo %d > %s/etc/ivic/nodes.yaml"%(webfarm_nodes, temp_path))
 
            os.system("sed -i \"s/^exit 0/setterm -blank 0 -powerdown 0\\nexit 0/\" " + temp_path + "/etc/rc.local")
            #os.system("sed -i -e \"s/^\(BLANK_TIME\)=.*/\\1=0/\" -e \"s/^\(POWERDOWN_TIME\)=.*/\\1=0/\" " + temp_path + "/etc/console-tools/config")             

            sysctl = open(temp_path+"/etc/sysctl.conf", "a")
            sysctl.write("\nnet.ipv4.ip_forward=1\n")
            sysctl.close()
             
        if(commands.getstatusoutput('umount  '+temp_path)[0]==0):
            commands.getstatusoutput('rm -r '+temp_path)
        logger.info(loop_dev);
        time.sleep(2);
        logger.info(commands.getstatusoutput('kvm-nbd --disconnect '+loop_dev)[1])
        time.sleep(1)
        return "OK"
    except Exception, e:
        #logging error message
        logger.info(commands.getstatusoutput('kvm-nbd --disconnect '+loop_dev)[1])
        logger.error("Failed to  modify vm property :"+str(e))
        sys.stdout.flush()
        return Null

#*****************************************************************************************#
def makeVMConfigureXML(hostname,uuid,vcpu,memory,vmImageFilePath,networkSources,type=0,passwd=None,cdrom_path=None):
     try:
         #<input type='mouse' bus='ps2'/>
         inputDevice = InputDevice("tablet","usb")

         #<graphics type='vnc' port='-1' listen='127.0.0.1'/>
         graphicalFramebuffer = GraphicalFramebuffer("vnc")
         graphicalFramebuffer.setPort("-1")
         graphicalFramebuffer.setListen("0.0.0.0")
         graphicalFramebuffer.setPassword(passwd)
   
         #<disk type='file' device='disk'>
         #      <source file='/var/civic/vmc/vmi/kvm/developer.img'/>
         # <target dev='hda' bus='ide'/>
         #</disk>
         diskDevice = DiskXml("file","disk")
         diskDevice.setSource(vmImageFilePath)
         if type == 0:
             diskDevice.setTarget('vda','virtio')
         else:
             diskDevice.setTarget('hda','ide')

         
         
         #<disk type='file' device='cdrom'>
         #      <source file='.../..iso'/>
         #      <target dev='hdc' bus='ide'/>
         #</disk>
         if cdrom_path != None:
                diskDevice2 = DiskXml("file","cdrom")
                diskDevice2.setSource(cdrom_path)
                diskDevice2.setTarget('hdc','ide')
                logger.info("cdrom_path found")
         else :
                logger.info("cdrom_path not found")
         
         #<emulator>/usr/bin/qemu-kvm</emulator>
         if type == 1:
             emulator = EmulatorXml("/usr/bin/kvm-win")
         else:
             emulator = EmulatorXml("/usr/bin/kvm")        
         
         if cdrom_path != None:        
             devices = [inputDevice,diskDevice,diskDevice2,emulator,graphicalFramebuffer]
             logger.info("diskDevice2 added")
         else:
             devices = [inputDevice,diskDevice,emulator,graphicalFramebuffer]
             logger.info("diskDevice2 not found")

         for i in range(len(networkSources)):
               # add by libo
               interfaceDevice = NetworkInterfaceXml("network")
               interfaceDevice.setSource(networkSources[i])
               interfaceDevice.setModel("virtio")
               devices.append(interfaceDevice)       

         domain = DomainXml("kvm",uuid,uuid)

         #vcpu default value is 1
         #current Memory is equal to memory
         #vcpu = "1"
         domain.setBasicResources(memory,memory,vcpu)    

         #setLifecycleControl (self,on_poweroff,on_reboot,on_crash)
         #<on_poweroff>destroy</on_poweroff>
         #<on_reboot>restart</on_reboot>
         #<on_crash>destroy</on_crash>
         domain.setLifecycleControl("destroy","restart","destroy")
    
         #set clock
         #<clock offset='utc'/>
         #setTimeKeeping(self, time)
         domain.setTimeKeeping("utc")        
         domain.setFeatures();
         
         #set operating system booting
         #setBIOSBootloader(self,type,loader,dev,arch,machine)
         domain.setBIOSBootloader("hvm","","hd","","")
         domain.setDevices(devices)    

         #domain xml for vm
         domainXML = domain.toXml()
         return domainXML
     except Exception,e:
         #add some logging message 
         return Null;

#*****************************************************************************************#

      
#*****************************************************************************************#
def makeXenVMConfigureXML(hostname,uuid,vcpu,memory,vmImageFilePath,networkSources):
     try:
         #<input type='mouse' bus='ps2'/>
         inputDevice = InputDevice("tablet","usb")

         #<graphics type='vnc' port='-1' listen='127.0.0.1'/>
         graphicalFramebuffer = GraphicalFramebuffer("vnc")
         graphicalFramebuffer.setPort("-1")
         graphicalFramebuffer.setListen("0.0.0.0") 
   
         #<disk type='file' device='disk'>
         #      <source file='/var/civic/vmc/vmi/kvm/developer.img'/>
         # <target dev='hda' bus='ide'/>
         #</disk>
         diskDevice = DiskXml("file","disk")
         diskDevice.setSource(vmImageFilePath)
         diskDevice.setTarget('hda','ide')        

         #<emulator>/usr/bin/qemu-kvm</emulator>
         #emulator = EmulatorXml("/usr/bin/kvm")        
         devices = [inputDevice,diskDevice,graphicalFramebuffer]

         for i in range(len(networkSources)):
               # add by libo
               interfaceDevice = NetworkInterfaceXml("network")
               interfaceDevice.setSource(networkSources[i])
               interfaceDevice.setModel("virtio")
               devices.append(interfaceDevice)       

         domain = DomainXml("xen",uuid,uuid)

         #vcpu default value is 1
         #current Memory is equal to memory
         #vcpu = "1"
         domain.setBasicResources(memory,memory,vcpu)    

         #setLifecycleControl (self,on_poweroff,on_reboot,on_crash)
         #<on_poweroff>destroy</on_poweroff>
         #<on_reboot>restart</on_reboot>
         #<on_crash>destroy</on_crash>
         #domain.setLifecycleControl("destroy","restart","destroy")
    
         #set clock
         #<clock offset='localtime'/>
         #setTimeKeeping(self, time)
         domain.setTimeKeeping("localtime")        
         domain.setFeatures();
         #set operating system booting
         #setBIOSBootloader(self,type,loader,dev,arch,machine)
         domain.setBIOSBootloader("hvm","/usr/lib/xen-3.2-1/boot/hvmloader","hd","","")
         domain.setDevices(devices)    

         #domain xml for vm
         domainXML = domain.toXml()
         return domainXML
     except Exception,e:
         #add some logging message
         logger.error("error when create VM configration file: %s", e) 
         return Null;

#*****************************************************************************************#

def create_windows_xp_interface(temp_path,address,netmask,gateway,dnsserver):
     try:
         file = open(temp_path,"w")
         try:
             file.write("pushd interface ip\r\n")
             file.write('set address name="" source=static addr='+address+' mask='+netmask+"\r\n")
             file.write('set address name="" gateway='+gateway+' gwmetric=0'+'\r\n')
             file.write('set dns name="" source=static addr='+dnsserver+' register=PRIMARY \r\n')
             file.write('set wins name="" source=static addr=none \r\n');
             file.write("popd\r\n")
             file.write("pushd interface ip\r\n")
             file.write('set address name="local" source=static addr='+address+' mask='+netmask+"\r\n")
             file.write('set address name="local" gateway='+gateway+' gwmetric=0'+'\r\n')
             file.write('set dns name="local" source=static addr='+dnsserver+' register=PRIMARY \r\n')
             file.write('set wins name="local" source=static addr=none \r\n');
             file.write("popd\r\n")
         finally:
             file.close()
         return 0;
     except Exception,e:
         logger.error(e)
         return -1;
def  create_exce_shell(filename,hostname):
     try:
         file = open(filename,"w")
         try:
             file.write("cls\r\n")
             file.write("netsh -f c:\\interfaces.txt\r\n")
             file.write('''@echo off
reg add "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\ComputerName\ComputerName" /v "ComputerName" /d " '''+hostname+''' " /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters" /v "NV Hostname" /d " '''+hostname+''' " /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters" /v "Hostname" /d " '''+hostname+''' " /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName" /v "ComputerName" /d " '''+hostname+''' " /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" /v "NV Hostname" /d " '''+hostname+''' " /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" /v "Hostname" /d " '''+hostname+''' " /f 
''');
         finally:
             file.close();
         return 0;
     except Exception,e:
         logger.info(e);
         return -1;
             

#*****************************************************************************************#



# INT signal handler
def signal_int_handler (sig, stack):
    logger.info("vmc server exits at %s", datetime.datetime.now().ctime())
    sys.exit(0)


# TERM signal handler
def signal_term_handler (sig, stack):
    logger.info("vmc server was killed at %s", datetime.datetime.now().ctime())
    sys.exit(0)


#CHLD signal handler, not used yet
def signal_chld_handler(sig, stack):
    #print "OpenVPN client disconnected from server. "
    try:
       os.wait()
    except:
       pass
    #os.waitpid(-1, os.WNOHANG)

''' 
Remove non-null directory
Not in use
'''
def RemoveNonNullDirectory (top):
    while 1:
        if os.path.exists(top):
            if len(os.listdir(top)) == 0:
                os.rmdir (top)
                break
            else:
                for root, dirs, files in os.walk(top, topdown=False):
                    for name in files:
                        os.remove(os.path.join(root, name))
                    for name in dirs:
                        os.rmdir(os.path.join(root, name))
        else:
            break


'''
function: mkdirs
'''
def mk_dir (dir):
     dir_list = dir.strip("/").split("/")
     path = ""
     for i in range(0, len(dir_list)) :
          path = path + "/" +dir_list[i]
          if not os.path.exists(path):
              os.mkdir(path)

#****************vmc server class********************#
class ServerClass:
    
    def __init__(self, config):
        self.imageRoot = config["image_root"]
        self.vmxmlRoot = config["vmxml_root"]
        self.networkRoot = config["network_root"]
        #self.port = "8989"
        self.rootfsRoot = config["rootfs_root"]
        self.nfsmountRoot = config["nfsmount_root"]
        self.vpnClient = config["openvpn_client"]
        self.vpnClient2 = config["ivic-vpn_client"]
        self.vpnprogram = config["ivic-vpn_program"]
        self.tmp = config["tmp"]
        self.hypervisor = config["hypervisor"]
        self.dns = config["dns"]
        os.putenv("PATH", os.getenv("PATH") + ":" + config["script_dir"] + "/vmc")
        socket.setdefaulttimeout(300) 
        self.nfs_action = Nfs_Action(config)
        self.nfs_action.mount_all_nfs()
	self.portal = config["portal_url"]
        #FIXME
        #conf = ConfigureVMC(VMC_CONF)
        #conf.configure()
        
        #if not isinstance(conf,ConfigureVMC):
        #    print "argument 2 not correct, need a ConfigureVMC instance"
        #    sys.exit(-1);
        #else:
        #    [self.imageRoot,self.vmxmlRoot,self.port,self.networkRoot,self.rootfsRoot, self.hypervisor] = conf.getConf();
        #modprobe nbd max_part=8
        os.system("modprobe nbd max_part=8")  

    def deployVSwitch(self,uuid,addr,type="openvpn",ip="",netmask="",dnet_params=[]):
        """deploy virtual switch"""
        try:            
            save_file_path = self.networkRoot           
            if not os.path.exists(save_file_path):
                mk_dir(save_file_path)

            #construct virtual switch configure xml file
            boot = []
            shutdown = []
            for dnets in dnet_params :
                for vport in dnets['internal_ports'] :
                   pport = dnets['external_ports'][dnets['internal_ports'].index(vport)]
                   start_cmd = 'iptables -t nat -A PREROUTING -p %s -d %s --dport %d -j DNAT --to %s:%d' % (dnets['protocol'], dnets['external_ip'], pport, dnets['internal_ip'], vport) 
                   stop_cmd = 'iptables -t nat -D PREROUTING -p %s -d %s --dport %d -j DNAT --to %s:%d' % (dnets['protocol'], dnets['external_ip'], pport, dnets['internal_ip'], vport) 
                   boot.append(start_cmd) 
                   shutdown.append(stop_cmd) 
            boot.append('iptables -F')
            xml_file_name = save_file_path+"/"+uuid+".xml"

            vSwitchXml = ""
            networkXml = NetworkXml(uuid,uuid)
            if (ip!=""):
                networkXml.setIP(ip,netmask)
                networkXml.setForward(mode="nat")
            
            name = uuid[0:13]
            networkXml.setBridge(name)
            networkXml.setShutdownScripts(shutdown);
            networkXml.setBootScripts(boot);
            vSwitchXml = networkXml.toXml()

            ret = saveXml2File(vSwitchXml, save_file_path, xml_file_name)
            if ret != 0:
                logger.error("Failed to create libvirt network %s configure file", uuid)
                #return ret
                return SaveFileERR  #return -1

            if type == 'openvpn':

                vpn_path = self.vpnClient + "/" + uuid
                if os.path.exists(vpn_path):
                    os.system("rm -r " + vpn_path)
                mk_dir(vpn_path)
                #os.mkdir(vpn_path)
                #print "Creating openvpn configuration files ...",
                #if self.createOpenVPNConf(uuid, addr) == 0:
                #   print "OK"
                #else:
                #   print "Failed"
                #   return -3

                if self.downloadCerts(addr, uuid) == 0:
                    logger.info("Downloading Configuration file, CA and client Certs ...OK")

                else:
                    logger.error("Downloading Configuration file, CA and client Certs ...Failed")
                    return DownLoadCertErr#return -2

            else :
               #if type == 'ivic-vpn':

                vpn_path = self.vpnClient2 + "/" + uuid
                if os.path.exists(vpn_path):
                    os.system("rm -r " + vpn_path)
                mk_dir(vpn_path)
                if self.downloadconf(addr.split(":")[0], uuid) == 0:
                    logger.info("Downloading Configuration file for ivic-vpn...OK")

                else:
                    logger.error("Downloading Configuration file for ivic-vpn ...Failed")
                    return DownLoadCertErr#return -2
            #else:
             #   logger.error("unknow switch type", uuid)
              #  return OtherException;#return -5          

            self.setType(uuid,type)   
            logger.info("Vnet %s has been successfully deployed.", uuid)
            return 0

        except Exception, e:
            logger.error("Vnet %s unsuccessfully deployed.", uuid)
            return OtherException #return -10
	


#****************************************************************************************************************#   
    def startVSwitch(self,uuid):
        '''
        function:start vswitch
        return :
        -3: OpenVPN configure error
	-2: Failed to open connection to the hypervisor
        -1: Failed to start network
        0: Succeed
        '''
        try:
            startVS_lock.acquire()
            xmlFilename = self.networkRoot+"/"+uuid.strip()+".xml"
            
            if not os.path.exists(xmlFilename):
                logger.error("cannot find vswitch configure file!")
		startVS_lock.release()
                return VSWConfNotExistErr #return -3;
            xmldoc = minidom.parse(xmlFilename)
            xmldesc = xmldoc.toxml()
            logger.info("sssss")  
            conn = libvirt.open(None)
            if conn == None:
                logger.error('Failed to open connection to the hypervisor')
                startVS_lock.release()
                return LibvirtOffErr; # return -4
            type = self.getType(uuid)
            if type == 'openvpn':
            
                openvpn = self.vpnClient + "/" + uuid.strip() + "/client.conf"

                if not os.path.exists(openvpn):
                    logger.error("cannot find VPN configure file!")
                    startVS_lock.release()
                    conn.close()
                    return VPNConfNotExistErr;#return -5

                try:
                    network = conn.networkLookupByName(uuid)
                except libvirt.libvirtError:
                    # if br is running, stop and del it
                    if commands.getstatusoutput("ifconfig " + uuid[0:13])[0] == 0:
                        commands.getstatusoutput("ifconfig " + uuid[0:13] + " down")
                        time.sleep(0.5)
                        commands.getstatusoutput("brctl delbr " + uuid[0:13])

                    network = conn.networkCreateXML(xmldesc)
                    if network == None:
                        logger.error("Starting vswitch %s ... Failed", uuid)
                        startVS_lock.release()
                        conn.close()
                        return CreateNetXMLErr;#return -6

                    if commands.getstatusoutput("ifconfig " + uuid[0:13] + " up")[0] != 0:
                        logger.error("Failed, vswitch off")
                        startVS_lock.release()
                        conn.close()
                        return IfconfigUPErr;#return -7

                    logger.info("Starting vswitch %s ... OK", uuid)

                    tap_name = self.createTapDev(uuid)
                    cmd = 'sed -i "s/^dev tap.*/dev ' + tap_name + '/" ' + openvpn
                    commands.getstatusoutput(cmd)
                    logger.info("ssswww")
                    self.OpenVPNConnToServer(uuid)
                    logger.info("vSwitch registered to server.")
                    logger.info("ifconfig %s 0.0.0.0"%(tap_name))
                    time.sleep(2)
                    commands.getstatusoutput("ifconfig "+tap_name+" 0.0.0.0")
                    
                    networkParse = NetworkParse(xmlFilename)
                    networkParse.parse();
                    for bootscript in networkParse.bootScripts:
                         bootscript = bootscript.strip();
                         logger.info(bootscript)
                         commands.getstatusoutput(bootscript)
                    startVS_lock.release()
                    conn.close()
                    return 0
                logger.warning("network %s exists.", uuid)
                conn.close()
                startVS_lock.release()
            else :
            #if type == 'ivic-vpn':
                ivicvpn = self.vpnClient2 + "/" + uuid.strip() + "/client.conf"
                if not os.path.exists(ivicvpn):
                    logger.error("cannot find VPN configure file!")
                    conn.close()
                    startVS_lock.release()
                    return VPNConfNotExistErr;#return -5
                try:
                    network = conn.networkLookupByName(uuid)
                except libvirt.libvirtError:
                    # if br is running, stop and del it
                    if commands.getstatusoutput("ifconfig " + uuid[0:13])[0] == 0:
                        commands.getstatusoutput("ifconfig " + uuid[0:13] + " down")
                        time.sleep(0.5)
                        commands.getstatusoutput("brctl delbr " + uuid[0:13])

                    network = conn.networkCreateXML(xmldesc)
                    if network == None:
                        logger.error("Starting vswitch %s ... Failed", uuid)
                        conn.close()
                        startVS_lock.release()
                        return CreateNetXMLErr;#return -6

                    if commands.getstatusoutput("ifconfig " + uuid[0:13] + " up")[0] != 0:
                        logger.error("Failed, vswitch off")
                        conn.close()
                        startVS_lock.release()
                        return IfconfigUPErr;#return -7

                    logger.info("Starting vswitch %s ... OK", uuid)

                    tap_name = self.createTapDev(uuid)
                    self.ivicVPNConnToServer(uuid,tap_name)
                    
                    logger.info("vSwitch registered to server.")
                    conn.close()
                    startVS_lock.release()
                    networkParse = NetworkParse(xmlFilename)
                    networkParse.parse();
                    for bootscript in networkParse.bootScripts:
                         bootscript = bootscript.strip();
                         logger.info(bootscript)
                         commands.getstatusoutput(bootscript)
                    return 0
                logger.warning("network %s exists.", uuid)
                conn.close()
                startVS_lock.release()
            #networkParse = NetworkParse(xmlFilename)
            #networkParse.parse();
            #for bootscript in networkParse.bootScripts:
                #bootscript = bootscript.strip();
                #logger.info(bootscript)
                #commands.getstatusoutput(bootscript)
            return 0;
        except Exception, e:
            logger.error("start VSwitch error: %s ... ", e)
            startVS_lock.release()
            return OtherException;
#****************************************************************************************************************#



#****************************************************************************************************************#
    def stopVSwitch(self,uuid):
        '''
        function: stop vswitch
        return :
        -3: Failed to get tap name of the switch 
        -2: Failed to open connection to the hypervisor
        -1: network don't exist
        0: Succeed
        '''
        try:
            conn = libvirt.open(None)
            if conn == None:
                logger.error('Failed to open connection to the hypervisor')
                return LibvirtOffErr;#return -4

            try:
                network = conn.networkLookupByName(uuid)
            except libvirt.libvirtError:
                logger.error("network %s don't exist", uuid)
                conn.close()
                return VSwitchOffErr;#return -8
            
            xmlFilename = self.networkRoot+"/"+uuid.strip()+".xml"
            if not os.path.exists(xmlFilename):
                logger.error("cannot find vswitch configure file!")
                conn.close()
                return VSWConfNotExistErr #return -3; 
            
            networkParse = NetworkParse(xmlFilename)
            networkParse.parse();
            for shutdownscript in networkParse.shutdownScripts:
                shutdownscript = shutdownscript.strip();
                logger.info(shutdownscript)
                commands.getstatusoutput(shutdownscript)
            
            type == self.getType(uuid)
            if type == 'openvpn':

                if self.OpenVPNDisConnect(uuid) == 0:
                    logger.info("Disconnected from server ... OK")
                else:
                    logger.warning("Disconnected from server ... Failed")

                tap = self.getTap(uuid)
                if tap == -1:
                    logger.warning("Detaching %s from vswitch ... Failed", tap)
                else:
                    logger.info("Detaching %s from vswitch ... OK", tap)

                if self.destroyTapDev(tap, uuid) == 0:
                    logger.info("Removing %s  ... OK", tap)
                else:
                    logger.warning("Removing %s  ... Failed", tap)



            else :
            #if type == 'ivic-vpn':

                if self.ivicVPNDisConnect(uuid) == 0:
                    logger.info("Disconnected from server ... OK")
                else:
                    logger.warning("Disconnected from server ... Failed")

                tap = self.getTap(uuid)
                if tap == -1:
                    logger.warning("Detaching %s from vswitch ... Failed", tap)
                else:
                    logger.info("Detaching %s from vswitch ... OK", tap)

                if self.destroyTapDev(tap, uuid) == 0:
                    logger.info("Removing %s  ... OK", tap)
                else:
                    logger.warning("Removing %s  ... Failed", tap)

            #else:
            #    logger.error("unknow switch type", uuid)
            #    return OtherException;#return -5
            
            if commands.getstatusoutput("ifconfig " + uuid[0:13] + " down")[0] != 0:
                logger.error("Cannot turn the vswitch off, vswitch still on!")
                conn.close()
                return IfconfigDownErr;#return -9

            ret = network.destroy()
            if ret == 0:
                logger.info("Destroying VSwitch ... OK")
                conn.close()
                return ret;
            else:
                logger.error("Destroying VSwitch ... Failed")
                conn.close()
                return DestroyVSwitchErr;#return -11;
               
        except Exception, e:
            logger.error("stop VSwitch error: %s ... ", e)
            return OtherException;
#****************************************************************************************************************#                  

      
#****************************************************************************************************************#      
    def startVM(self,uuid):
        '''
        function: start vm
        return :
        -4: Failed to start vm 
        -3: Failed to parse domain xml
        -2: Failed to open connection to the hypervisor
        -1: Failed to start network
        0: Succeed
        '''  
        try:
            xmlFilename = self.vmxmlRoot+"/"+uuid.strip()+".xml"
            logger.info("xmlFilename:"+xmlFilename) 
            ret = getNameFromDomainXML(xmlFilename)            
            if ret == Null:
                logger.error("Failed to parse domain xml")
                return ParseConfErr;#return -12;
            else:
                name = ret[0]
                xmldesc = ret[1]
 
            conn = libvirt.open(None)
            if conn == None:
               logger.error('Failed to open connection to the hypervisor')
               return LibvirtOffErr;#return -4;
            try:
                # add by libo
                dom = conn.lookupByUUIDString(uuid)
            except libvirt.libvirtError:
                networkUUIDs = getNetworkFromDomain(xmldesc);
                conn.close()  
                for i in range(len(networkUUIDs)):
                     ret = self.startVSwitch(networkUUIDs[i]);
                     if ret != 0:
                        return StartVSwitchErr;#return -13
                conn = libvirt.open(None)
                try:
                     dom = conn.createLinux(xmldesc, 0)
                except libvirt.libvirtError:
                     logger.error("Starting domain %s ... Failed", name)
                     conn.close()
                     return CreateVMErr;#return -14

                if dom == None:
                     logger.error("Starting domain %s ... Failed", name)
                     conn.close()
                     return CreateVMErr;#return -14
                else:
                     logger.info("Starting domain %s ... OK", name)
                     time.sleep(0.5)
                     logger.info("ivic-monitor")
                     commands.getstatusoutput("ivic-monitor")
                     conn.close()
                     return 0

            logger.warning("VM %s is running, skip the VM create command.", name)
            conn.close()
            return 0
        except Exception, e:
            logger.error("start VM error: %s ... ", e)
            if conn!=None:
               conn.close()
            return OtherException;#return -10 
#****************************************************************************************************************#	
       


#****************************************************************************************************************#
#add by jch
 
    def hibernateVM(self, uuid):
         xmlFile = self.vmxmlRoot + "/" + uuid + ".xml"         
         imgPath = getImagePathFromDomainXML(xmlFile)
         FilePath = os.path.dirname(imgPath)
         conn = libvirt.open(None)
         if conn == None:
             logger.error('Failed to open connection to the hypervisor')
             return LibvirtOffErr;
         try:
             dom = conn.lookupByUUIDString(uuid)
             dom.save(FilePath+"/"+uuid+"-saved");
             logger.info("succed to save vm")
             conn.close()
             return 0;
         except libvirt.libvirtError:
             logger.error( "dom do not exist");
             conn.close()
             return HibernateVMErr;

    def resumeVM(self,uuid):
         xmlFile = self.vmxmlRoot + "/" + uuid + ".xml"
         imgPath = getImagePathFromDomainXML(xmlFile)
         FilePath = os.path.dirname(imgPath)
         logger.info(FilePath)
         conn = libvirt.open(None)
         if conn == None:
             logger.error('Failed to open connection to the hypervisor')
             return LibvirtOffErr;             
         try:
             logger.info(FilePath+"/"+uuid+"-saved");
             if not os.path.exists(FilePath+"/"+uuid+"-saved"):
                 logger.error("failed to resume vm: file not exists")
                 conn.close()
                 return FileNotExistsErr;

             conn.restore(FilePath+"/"+uuid+"-saved");
             logger.info("succed to save vm")
             conn.close()
             return 0;
         except Exception,err:
             logger.error("Failed to resume vm: %s"%(str(err)))
             conn.close()
             return ResumeVMErr;
#imgPath = getImagePathFromDomainXML(xmlFile)
    def snapshotVM(self,uuid,snapshot_id):
         xmlFile = self.vmxmlRoot + "/" + uuid + ".xml"
         imgPath = getImagePathFromDomainXML(xmlFile)
         FilePath = os.path.dirname(imgPath)

         conn = libvirt.open(None)
         if conn == None:
             logger.error('Failed to open connection to the hypervisor')
             return LibvirtOffErr;
         try:
             dom = conn.lookupByUUIDString(uuid)
             dom.save(FilePath+"/"+uuid+"-saved-"+snapshot_id);
             os.system("cp "+imgPath+" "+imgPath+"-"+snapshot_id)
             conn.restore(FilePath+"/"+uuid+"-saved-"+snapshot_id)
             logger.info("succed to save vm")
             conn.close()
             return 0;
         except Exception,e:
             logger.error( "dom do not exist %s ",e);
             conn.close()
             return SnapShotVMErr;

    def rollbackVM(self,uuid,snapshot_id):
         xmlFile = self.vmxmlRoot + "/" + uuid + ".xml"
         imgPath = getImagePathFromDomainXML(xmlFile)
         FilePath = os.path.dirname(imgPath)

         if (not os.path.exists(FilePath+"/"+uuid+"-saved-"+snapshot_id)) or (not os.path.exists(imgPath+"-"+snapshot_id)):
             #logger.error("Snapshot File not exists")
             return FileNotExistsErr

         conn = libvirt.open(None)
         if conn == None:
             #logger.error('Failed to open connection to the hypervisor')
             return LibvirtOffErr;
         try:
             dom = conn.lookupByUUIDString(uuid)
             dom.save(FilePath+"/"+uuid+"-saved-"+snapshot_id+"_temp");
             os.system("cp "+imgPath+"-"+snapshot_id+" "+imgPath)
             time.sleep(1)
             conn.restore(FilePath+"/"+uuid+"-saved-"+snapshot_id)
             os.system("rm "+FilePath+"/"+uuid+"-saved-"+snapshot_id+"_temp -f")
             #logger.info("succed to save vm")
             conn.close()
             return 0;
         except libvirt.libvirtError:
             #logger.error( "dom do not exist");
             conn.close()
             return RollbackVMErr;

    def startpcapVM(self,vmiuuid,nics,expr):
         try:
             pcap = Pcap(vmiuuid,nics,expr);
             pcap.start();
             logger.info("start pcap vm ok");
             return 0;
         except Exception,e:
             logger.error(str(e));
             return StartPcapErr;
    def stoppcapVM(self,vmiuuid,nics):
         try:
             pcap = Pcap(vmiuuid,nics);
             pcap.stop();
             logger.info("stop pcap vm ok");
             return 0;
         except Exception,e:
             logger.error(str(e));
             return StopPcapErr;

#****************************************************************************************************************#


    
#****************************************************************************************************************#	
    def stopVM(self,uuid,stop_mode):
        '''
        function: stop vm
        return :
        -3: vm don't exist
        -2: Failed to open connection to the hypervisor
        -1: Failed to shutdown vm 
        0: Succeed
        ''' 
        conn = libvirt.open(None)
        if conn == None:
            logger.error('Failed to open connection to the hypervisor')
            return LibvirtOffErr;#return -4

        try:
            dom = conn.lookupByUUIDString(uuid)
            name = dom.name();
            ret = 0 
            if stop_mode == 'destroy':
                ret =  dom.destroy()
            else:
                ret =  dom.shutdown()
            if ret == 0:
                logger.info("Succeed to shutdown vm %s",name)
                conn.close()
                return 0
            else:
                logger.error("Failed to shutdown vm %s",name)
                conn.close()
                return ShutdownVMErr;#return -15

        except libvirt.libvirtError, e:
            #logger.error("VM does't exist!")
            #return OtherException;#return -10;  
            conn.close()
            return 0;
#****************************************************************************************************************#	

#new delployvm************************************************************************************#	
    def deployVM(self,uuid,xml,webfarm_nodes=None):
        try:                        
            if uuid == None or uuid.strip() == "":
                #logging error message
                return UUIDNullErr;#return -16

            logger.info(xml)

            uuid=uuid.strip()
            lock.acquire()
            #get basic info from xml
            (templateXMLURI,hostname,memory,diskSize,passwd) = getAllBasicInfo(xml)
            diskSize = diskSize.strip()
            diskSize = diskSize[0:len(diskSize)-1]

	    #print xml 
            memory = memory.strip()
            memory = memory.lower()
            if not memory.isdigit():
                if memory[-1]=='g':
                    memory = int(memory[0:len(memory)-1])*1024*1024
                elif memory[-1]=='m':
                    memory = int(memory[0:len(memory)-1])*1024
                else:
                    memory = int(memory[0:-1])
            else:
                memory = int(memory)*1024
            memory = str(memory)

            networkSources = getAllNetworkSource(xml)
            #end get basic info from xml        

            #get deploy info from template xml  
            (rootfs_url,deploy_method,guestOS_type,cowdir_url,vcpu) = getDeployInfoFromVMT(templateXMLURI)
            vcpu = vcpu.strip()
            if rootfs_url == None:  
                  logger.error("Downloading VM Description File from vStore... Failed")  
                  lock.release()  
                  return DownloadRFSErr 

            cdrom_url = getCdromURLFromURL(templateXMLURI)
            if cdrom_url == "" :
                 logger.info("cdrom_url is none")
                 cdrom_path = None     
            else :
                 local_base_dir = self.nfs_action.get_local_base_path(cdrom_url)
                 array = cdrom_url.split("://")
                 host_path_file = array[1]
                 array = host_path_file.split("/",1)
                 host = array[0]
                 path_file = array[1]
                 path_file = "/"+path_file
                 file = os.path.basename(path_file)
                 cdrom_path = local_base_dir+"/"+file

            guestOS_type=guestOS_type.strip()
            rootfs_url = rootfs_url.strip()
            logger.info("rootfs_url:"+rootfs_url)
            deploy_method = deploy_method.strip()
            if deploy_method == "nfsmount":
                 
                 vm_image_absFileName = self.nfs_action.mount_nfs(rootfs_url,cowdir_url,uuid,logger)
                 logger.info(vm_image_absFileName)
                 if(modify_nfsmount_image(guestOS_type,vm_image_absFileName,hostname,diskSize,xml,self.portal, uuid,webfarm_nodes)==Null):
                     logger.error("Failed to configure VM property")
            else:
                 #download rootfs from vStore
                 logger.info("download")
                 rootfsFileName = downloadRootfs(rootfs_url,self.rootfsRoot)

                 if rootfsFileName == None:
                      logger.error("Downloading VM root file system from vStore... Failed")
                      lock.release()
                      return DownloadRFSErr;#return -17;
                 logger.info("Downloading VM root file system from vStore... OK")

                 #create vm image file
                 vmImagePath=self.imageRoot+"/"+uuid
                 if not os.path.exists(vmImagePath):
                      mk_dir(vmImagePath)
                 vm_image_absFileName = createVMImage(guestOS_type,rootfsFileName,vmImagePath,hostname,diskSize,xml,uuid)
            #end if
            if vm_image_absFileName == None:
                 logger.error("Creating VM image ... Failed")
                 lock.release()
                 return CreateVMImgErr;#return -18
            logger.info("Creating VM image ... OK") 
            #make libvirt domain configure xml
            if guestOS_type.find("windows")==-1:
                 type = 0
            else:
                 type = 1

            logger.info("vm_image_absFileName"+vm_image_absFileName)
            if self.hypervisor == "kvm":
                domainXML=makeVMConfigureXML(hostname,uuid,vcpu,memory,vm_image_absFileName,networkSources,type,passwd,cdrom_path)
            if self.hypervisor == "xen":
                domainXML=makeXenVMConfigureXML(hostname,uuid,vcpu,memory,vm_image_absFileName,networkSources)
            if domainXML==None:
                logger.error("Creating VM configuration file ... Failed")
                lock.release()
                return SaveFileErr;

            xmlSaveFilename = self.vmxmlRoot +"/"+uuid+".xml"
            if not os.path.exists(self.vmxmlRoot):
                mk_dir(self.vmxmlRoot)
         
            ret = saveXml2File(domainXML,self.vmxmlRoot,xmlSaveFilename)
            if ret != 0:
                logger.error("Saving VM configuration file ... Failed")
                lock.release()
                return SaveFileErr;#return -1

            logger.info("Creating VM configuration file ... OK")
            logger.info("VM %s has been successfully deployed.", uuid)
            lock.release()	    
            return 0
        except Exception, ex:
            lock.release()
            logger.error('deploying vm happen Exception: %s', str(ex))
            return OtherException;#return -10
              
#new delployvm************************************************************************************#	
    
###################################################################################################
#function: clone vm
#author: jch
#date: 2009-06-22

    def cloneVM(self,uuid,vnode_xml):
        #import Vnode
        try:
            logger.info("start clone")
            if uuid == None or uuid.strip() == "":
                logger.error("invalid uuid!")
                return UUIDNullErr;#return -16

            uuid=uuid.strip()
            lock.acquire()
            
            vnode = Vnode(vnode_xml);
            vnode.parse();
            
            if vnode.deployMethod=="nfsmount":
                local_cow_dir = self.nfs_action.mount_nfs(vnode.downloadLink,vnode.cowdir,"",logger)
                #download cow image
                if commands.getstatusoutput("wget "+vnode.diskRef+" -O "+local_cow_dir+"/"+uuid+".img")[0]!=0:
                   lock.release()
                   logger.error("download disk ref error:"+vnode.diskRef)
                   return DownloadDiskRefErr;
                vm_image_absFileName = local_cow_dir+"/"+uuid+".img"
            else:
                if not os.path.exists(self.vmxmlRoot):
                    mk_dir(self.vmxmlRoot)
                diskImagePath = self.vmxmlRoot+"/"+uuid

                if not os.path.exists(diskImagePath):
                    mk_dir(diskImagePath)
                vm_image_absFileName = diskImagePath+"/"+vnode.hostname+".img"
                if commands.getstatusoutput("wget "+vnode.diskRef+" -O "+vm_image_absFileName)[0]!=0:
                   lock.release()
                   logger.error("download disk ref error:"+vnode.diskRef)
                   return DownloadDiskRefErr;
             
            if commands.getstatusoutput("wget "+vnode.memRef+" -O "+vm_image_absFileName[0:-4]+"-saved")[0]!=0:
                lock.release()
                logger.error("download mem ref error:"+vnode.memRef)
                return DownloadMemRefErr;
            
            memImage = MemImage(vm_image_absFileName[0:-4]+"-saved",uuid,vnode.networkSources,vm_image_absFileName)
            memImage.modify();
             
            #gen libvirt configuration file
            logger.info("Creating clone  VM image ... OK")
            #make libvirt domain configure xml
            if vnode.osType.find("windows")==-1:
                type = 0
            else:
                type = 1
            #By lanbo
            #we should obtain vcpu info from the vnode_xml, the code now is incomplete and i will add the code later
            vcpu=1
            if self.hypervisor == "kvm":
                domainXML=makeVMConfigureXML(vnode.hostname,uuid,vcpu,vnode.memory,vm_image_absFileName,vnode.networkSources,type,vnode.passwd)
            if self.hypervisor == "xen":
                domainXML=makeXenVMConfigureXML(vnode.hostname,uuid,vcpu,vnode.memory,vm_image_absFileName,vnode.networkSources)
            if domainXML==None:
                logger.error("Creating VM configuration file ... Failed")
                lock.release()
                return SaveFileErr;

            xmlSaveFilename = self.vmxmlRoot +"/"+uuid+".xml"
            if not os.path.exists(self.vmxmlRoot):
               mk_dir(self.vmxmlRoot)

            ret = saveXml2File(domainXML,self.vmxmlRoot,xmlSaveFilename)
            if ret != 0:
               logger.error("Saving VM configuration file ... Failed")
               lock.release()
               return SaveFileErr;#return -1

            logger.info("Creating VM configuration file ... OK")
            logger.info("VM %s has been successfully deployed.", uuid)
            lock.release()
            return 0               
        except Exception,e:
            lock.release();
            logger.error("failed to clone vm:"+str(e));
            return CloneVMErr;   

###################################################################################################


#***********************************deploy VM info**** **********************************************#
    def deployVMInfo(self,uuid,xml):
        try:
            if uuid == None or uuid.strip() == "":
                #logging error message
                return UUIDNullErr;#return -16

            uuid=uuid.strip()
            lock.acquire()
            #get basic info from xml
            (templateXMLURI,hostname,memory,diskSize,passwd) = getAllBasicInfo(xml)
            diskSize = diskSize.strip()
            diskSize = diskSize[0:len(diskSize)-1]

            #print xml
            memory = memory.strip()
            memory = memory.lower()
            if not  memory.isdigit():
                if memory[-1]=='g':
                    memory = int(memory[0:len(memory)-1])*1024*1024
                elif memory[-1]=='m':
                    memory = int(memory[0:len(memory)-1])*1024
                else:
                    memory = int(memory[0:-1])
            else:
                memory = int(memory)
            memory = str(memory)

            networkSources = getAllNetworkSource(xml)
            #end get basic info from xml

            #get deploy info from template xml
            (rootfs_url,deploy_method,guestOS_type,cowdir_url) = getDeployInfoFromVMT(templateXMLURI)
            if rootfs_url == None:
                  logger.error("Downloading VM Description File from vStore... Failed")
                  lock.release()
                  return DownloadRFSErr

            guestOS_type=guestOS_type.strip()
            rootfs_url = rootfs_url.strip()
            deploy_method = deploy_method.strip()
            if deploy_method == "nfsmount":
                 local_cow_dir = self.nfs_action.mount_nfs(rootfs_url,cowdir_url,"",logger)
                 vm_image_absFileName = local_cow_dir+"/"+uuid+".img"
            else:
                 #create vm image file
                 vmImagePath=self.imageRoot+"/"+uuid
                 vmImagePath=self.imageRoot+"/"+uuid
                 vm_image_absFileName = vmImagePath+"/"+hostname.strip()+".img"
            #make libvirt domain configure xml
            if guestOS_type.find("windows")==-1:
                 type = 0
            else:
                 type = 1
            #By lanbo
            #we should obtain vcpu info from the vnode_xml, the code now is incomplete and i will add the code later
            vcpu=1
            if self.hypervisor == "kvm":
                domainXML=makeVMConfigureXML(hostname,uuid,vcpu,memory,vm_image_absFileName,networkSources,type,passwd)
            if self.hypervisor == "xen":
                domainXML=makeXenVMConfigureXML(hostname,uuid,vcpu,memory,vm_image_absFileName,networkSources)
            if domainXML==None:
                logger.error("Creating VM configuration file ... Failed")
                lock.release()
                return SaveFileErr;

            xmlSaveFilename = self.vmxmlRoot +"/"+uuid+".xml"
            if not os.path.exists(self.vmxmlRoot):
                mk_dir(self.vmxmlRoot)

            ret = saveXml2File(domainXML,self.vmxmlRoot,xmlSaveFilename)
            if ret != 0:
                logger.error("Saving VM configuration file ... Failed")
                lock.release()
                return SaveFileErr;#return -1

            logger.info("Creating VM configuration file ... OK")
            logger.info("VM %s has been successfully deployed.", uuid)
            lock.release()
            return 0
        except Exception, ex:
            lock.release()
            logger.error('deploying vm happen Exception: %s', str(ex))
            return OtherException;#return -10
 
#***********************************end deploy vm info***********************************************#

#****************************************************************************************************************#       
    '''
    fuction:  undeploy a vm
    return :  0 for success; -1 -2 -3 for error
    '''
    def undeployVM(self,uuid):
        imgRoot = self.imageRoot
        xmlRoot = self.vmxmlRoot
        diskImgPath = ""

        if uuid.strip() == "" or uuid == None:
            #return -1
            return UUIDNullErr;#return -16

        imgPath = imgRoot +"/"+ uuid
        diskImgPath = imgPath
        xmlFile = xmlRoot + "/" + uuid + ".xml"

        
	if not os.path.exists(imgPath):
            imgPath = getImagePathFromDomainXML(xmlFile)
            imgPath = imgPath.strip()
            diskImgPath = imgPath
            imgPath = imgPath[0:-4]
        if os.path.exists(xmlFile):
            os.remove(xmlFile) 
        if not os.path.exists(diskImgPath):
            logger.warning("Cannot undeploy VM: VM image does not exist!")
            return VMImgNotExistErr;#return -19;

        if commands.getstatusoutput("rm -r " + imgPath+"*")[0] == 0:
            logger.info("VM %s has been successfully undeployed.", uuid)
            return 0
        else:
            logger.error("VM Undeploy error: cannot remove VM directory!")
            return RemoveVMDirErr;#return -20

    '''
    fuction:  migrate a vm
    return :  0 for success; others for error
    '''
    def migrateVM(self,uuid, dest):
        conn = libvirt.open(None)
        if conn == None:
            logger.error('Failed to open connection to the hypervisor')
            return LibvirtOffErr;#return -4
        if self.hypervisor == "xen":
            dconn = libvirt.open("xen+ssh://" + dest)
        if self.hypervisor == "kvm":
            dconn = libvirt.open("qemu+ssh://" + dest + "/system")
        if dconn == None:
            logger.error('Failed to open connection to the remote hypervisor')
            return DconnErr
        
        try:
            migrate_dom = conn.lookupByUUIDString(uuid)
        except:
            logger.error("Cannot find the VM %s to be migrated.", uuid)
            conn.close()
            dconn.close()
            return DomainByUUIDNotFoundErr

        try:
            migrate_dom.migrate(dconn, libvirt.VIR_MIGRATE_LIVE, None, None, 0)
        except Exception, e:
            logger.error("Error during migration: %s", e)
            conn.close()
            dconn.close()
            return MigFailErr
        
        logger.info("VM %s migrated to %s", uuid, dest)
        #print_or_log("VM " + uuid + " migrated to " + dest, "info")

        vswitch_uuid = self.getVswitch(uuid)
        for l in vswitch_uuid:
	    stype = self.getType(l)
	    logger.info("switch %s type is %s", l, stype)
            if stype == 'ivic-vpn':
                try:
                    pid = self.getPid(l)
                    logger.info("pid:%s",pid)
		    #commands.getstatusoutput("kill -s SIGUSR1 " + pid)
                    try:
                        os.kill(int(pid), signal.SIGUSR1)
                    except Exception, e:
                        logger.error("ivic-vpn:send SIGUSR1 error: ", e)
                    logger.info("send SIGUSR1 to pid: %s", pid)
                except Exception, e:
                    logger.error("for ivic-vpn: send SIGUSR1 error : ", e)	
        conn.close()
        dconn.close()
        return 0
    '''
    function: Dnat configuration
    add by libo: 09.09.30
    '''   
    def confDnat(self, uuid, dnet_params=[]):
        boot = []
        shutdown = []
        for dnets in dnet_params :
            for vport in dnets['internal_ports'] :
                pport = dnets['external_ports'][dnets['internal_ports'].index(vport)]
                start_cmd = 'iptables -t nat -A PREROUTING -p %s -d %s --dport %d -j DNAT --to %s:%d' % (dnets['protocol'], dnets['external_ip'], pport, dnets['internal_ip'], vport) 
                stop_cmd = 'iptables -t nat -D PREROUTING -p %s -d %s --dport %d -j DNAT --to %s:%d' % (dnets['protocol'], dnets['external_ip'], pport, dnets['internal_ip'], vport) 
                boot.append(start_cmd) 
                shutdown.append(stop_cmd) 
        boot.append('iptables -F')
        for iptables in boot:
            os.system(iptables)
        return 0

    '''
    fuction:  start a new process
    return :  pid of the new process
    '''
    def run(self, program, *args):
        pid = os.fork()    	
        if not pid:
           close_all()
           #os.close(0)
           #os.close(1)
           #os.close(2)
           #os.open('/dev/null', os.O_RDONLY)
           #os.open('/dev/null', os.O_WRONLY)
           #os.dup(1)
           os.execvp(program, (program,) +  args)
        return pid
    
    # run openvpn client as a daemon, not used yet
    def openvpn_client_daemonized(self):
	# Become the group leader (already a child process)
        os.setsid()
        pid = os.fork()

        if pid:
           os._exit(0)

        os.close(0)
        os.close(1)
        os.close(2)
        close_all()
        
        os.open('/dev/null', os.O_RDONLY)
        os.open('/dev/null', os.O_WRONLY)
        os.dup(1)
        os.open(LOG_FILE, os.O_WRONLY|os.O_CREAT|os.O_APPEND)
        os.dup(1)

    # get tap info from vswitch tmp file
    # vswitch is used to keep the current info of vswitchs
    # When server restarted, it can still restore tap info
    def getTap (self, vnet_uuid):
        if not os.path.exists(self.tmp+VSWITCH):
           logger.error("Cannot find vswitch->tap map file!")
           return -1
        cf = ConfigParser.ConfigParser()
        cf.read(self.tmp+VSWITCH)
        try:
            res = cf.get("tap", vnet_uuid)
            return res
        except:
            logger.error("No Tap entry for vswitch %s", vnet_uuid)
            return -1

    def getPid (self, vnet_uuid):
        if not os.path.exists(self.tmp+VSWITCH):
           print "Cannot find vswitch ->openvpn pid map file!"
           return -1
        cf = ConfigParser.ConfigParser()
        cf.read(self.tmp+VSWITCH)
        try:
            res = cf.get("pid", vnet_uuid)
            return res
        except:
            logger.error("No Pid entry for vswitch %s", vnet_uuid)
            return -1

    def getType(self,vnet_uuid):
        if not os.path.exists(self.tmp+VSWITCH):
           print "Cannot find vswitch ->type map file!"
           return -1
        cf = ConfigParser.ConfigParser()
        cf.read(self.tmp+VSWITCH)
        try:
            res = cf.get("type", vnet_uuid)
            return res
        except:
            logger.error("No type entry for vswitch %s", vnet_uuid)
            return -1

    def getVswitch(self, uuid):
        xmlFile = self.vmxmlRoot + "/" + uuid + ".xml"
        if not os.path.exists(xmlFile):
            logger.error("can't find %s xmlfile",uuid)
        xmldoc = minidom.parse(xmlFile)
        xmldesc = xmldoc.toxml()
        vswitch = getNetworkFromDomain(xmldesc)
        logger.info("VM %s vswitch is %s", uuid, vswitch)
        return vswitch

    def setType(self,vnet_uuid,stype):
        cf = ConfigParser.ConfigParser()
    
        if not os.path.exists(self.tmp):
           mk_dir(self.tmp)

        if not os.path.exists(self.tmp+VSWITCH):
           os.system("touch " + self.tmp+VSWITCH)

        cf.read(self.tmp+VSWITCH)
        if "type" not in cf.sections():
           cf.add_section("type")
        cf.set("type", vnet_uuid, stype)
        cf.write(open(self.tmp+VSWITCH, "w"))

    def setTap (self, vnet_uuid, tap):
        cf = ConfigParser.ConfigParser()
    
        if not os.path.exists(self.tmp):
           mk_dir(self.tmp)

        if not os.path.exists(self.tmp+VSWITCH):
           os.system("touch " + self.tmp+VSWITCH)

        cf.read(self.tmp+VSWITCH)
        if "tap" not in cf.sections():
           cf.add_section("tap")
        cf.set("tap", vnet_uuid, tap)
        cf.write(open(self.tmp+VSWITCH, "w"))

    def setPid (self, vnet_uuid, pid):
        cf = ConfigParser.ConfigParser()
 
        if not os.path.exists(self.tmp):
           mk_dir(self.tmp)

        if not os.path.exists(self.tmp+VSWITCH):
           os.system("touch " + self.tmp+VSWITCH)

        cf.read(self.tmp+VSWITCH)
        if "pid" not in cf.sections():
           cf.add_section("pid")   
        cf.set("pid", vnet_uuid, pid)
        cf.write(open(self.tmp+VSWITCH, "w"))

    def rmVnet (self, vnet_uuid):
        cf = ConfigParser.ConfigParser()
        cf.read(self.tmp+VSWITCH)

        cf.remove_option("tap", vnet_uuid)
        cf.remove_option("pid", vnet_uuid)
        cf.remove_option("type", vnet_uuid)
        cf.write(open(self.tmp+VSWITCH, "w"))

    '''
    fuction:  create a tap device
    return :  tap name
    '''
    def createTapDev(self, vnet):
        res = commands.getstatusoutput("openvpn --mktun --dev tap")[1]
        tap = re.search('tap[0-9]+', res).group()
	
        self.setTap(vnet, tap)
	#vnet_tap_map[vnet] = tap
        cmd = "brctl addif " + vnet[0:13] + " " + tap
        os.system(cmd)
        return tap

    '''
    fuction:  create a tap device by "tunctl"
    return :  tap name
    '''
    def createTap(self, vnet):
        res = commands.getstatusoutput("tunctl")[1]
        tap = re.search('tap[0-9]+', res).group()
	
        self.setTap(vnet, tap)
	#vnet_tap_map[vnet] = tap
        cmd = "brctl addif " + vnet[0:13] + " " + tap
        os.system(cmd)
        cmd = "ifconfig "+ tap + " up"
        os.system(cmd)
        return tap


    '''
    fuction:  download CA cert, client cert and client key
              addr: server address      vnet: uuid of vnet
    return :  0 for success
              -1 for failed
    '''
    def downloadCerts(self, ip, vnet):
        vnet_dir = self.vpnClient + "/" + vnet
        url = 'http://' + ip + '/vswitch/openvpn/' + vnet
        
        #os.chdir(vnet_dir)
        if not os.path.exists(vnet_dir):
            mk_dir(vnet_dir)
            #os.system("mkdir " + vnet_dir)
	
        if commands.getstatusoutput("wget " + url + '/client.conf' + " -P " + vnet_dir)[0] != 0:
            return DownLoadCertErr
        if commands.getstatusoutput("wget " + url + '/ca.crt' + " -P " + vnet_dir)[0] != 0:
            return DownLoadCertErr
        if commands.getstatusoutput("wget " + url + '/client.crt' + " -P " + vnet_dir)[0] != 0:
            return DownLoadCertErr
        if commands.getstatusoutput("wget " + url + '/client.key' + " -P " + vnet_dir)[0 != 0]:
            return DownLoadCertErr
	os.system('''vnpconf='''+vnet_dir+'''/client.conf;client_key=`cat /etc/ivic/monitor.yaml|awk '$1=="client_key:"{print $2}'`;server_key=`cat /etc/ivic/monitor.yaml|awk '$1=="server_cert:"{print $2}'`;cat ${vnpconf} | awk -v client=``${client_key}`` -v server=``${server_key}`` '{if($1=="ca"){print "ca "server; }else if($1=="cert"||$1=="key"){print $1" "client;}else{print;}}'>${vnpconf}.bk;mv ${vnpconf}.bk ${vnpconf} -f''')
        return 0


    '''
    fuction:  download conf for ivic-vpn
              addr: server address      vnet: uuid of vnet
    return :  0 for success
              -1 for failed
    '''
    def downloadconf(self, ip, vnet):
        vnet_dir = self.vpnClient2 + "/" + vnet
        url = 'http://' + ip + ':8080/vswitch/ivic-vpn/' + vnet
        
        #os.chdir(vnet_dir)
        if not os.path.exists(vnet_dir):
            mk_dir(vnet_dir)
            #os.system("mkdir " + vnet_dir)
	
        if commands.getstatusoutput("wget " + url + '/client.conf' + " -P " + vnet_dir)[0] != 0:
            return DownLoadCertErr
        return 0

    #'''
    #fuction:  create openvpn configuration file
    #return :  0 for success
    #'''
    #def createOpenVPNConf(self, vnet, addr):
    #    conf = "client.conf"
    #    [ip, port] = addr.split(":")
    #    
    #    os.chdir("/etc/openvpn/" + vnet)
    # 
    #    #Sample file doesn't exist
    #    if not os.path.exists("/etc/openvpn/client-sample.conf"):
    #       print "Sample file doesn't exist!"
    #       return -1
    #       
    #    cmd = "cp /etc/openvpn/client-sample.conf " + conf 
    #    os.system(cmd)
    #    cmd = 'sed -i "s/^remote .*/remote ' + ip + " " + port + '/" ' + conf
    #    os.system(cmd)
    #    return 0
	
    '''
    fuction:  OpenVPN client connects to Server
    return :  0 for success; -1 for failed
    '''    
    def OpenVPNConnToServer(self, vnet):
        old_dir = os.getcwd()
        conf_path = self.vpnClient + "/" + vnet
        os.chdir(conf_path)
        conf = "client.conf"
        if not os.path.exists(conf):
            logger.error("Cannot find openvpn client configuration file!")
            return VPNConfNotExistErr
        pid = self.run("openvpn", conf)
        self.setPid(vnet, str(pid))
        os.chdir(old_dir)
	#vnet_pid_map[vnet] = str(pid)
        return 0


    '''
    fuction:  ivicVPN client connects to Server
    return :  0 for success; -1 for failed
    '''    
    def ivicVPNConnToServer(self, vnet, tap_name):
        old_dir = os.getcwd()
        conf_path = self.vpnClient2 + "/" + vnet
        os.chdir(conf_path)
        pid = os.fork()
        if not pid:
           close_all()
           os.execvp(self.vpnprogram+"/ivic-vnet-client", [self.vpnprogram+"/ivic-vnet-client" ,tap_name, "client.conf"])
        self.setPid(vnet, str(pid))
        os.chdir(old_dir)
        return 0


    '''
    fuction:  OpenVPN client disconnects from Server
    return :  0 for success; -1 for failed
    '''  
    def OpenVPNDisConnect(self, vnet):
        pid = self.getPid(vnet)
        if pid == -1:
           return -1
	#try:
	#   os.kill(pid, signal.SIGTERM)
	#except:
	#   print "openvpn kill error"
	#return 0
        if commands.getstatusoutput("kill -9 " + pid)[0] != 0:
            logger.warning("Failed to kill openvpn process!")
            return -1
        return 0
        

    '''
    fuction:  ivic-vpn client disconnects from Server
    return :  0 for success; -1 for failed
    '''  
    def ivicVPNDisConnect(self, vnet):
        pid = self.getPid(vnet)
        if pid == -1:
           return -1
	try:
	   os.kill(int(pid), signal.SIGTERM)
	except:
	   print "ivicvpn kill error"
	return 0


    '''
    fuction:  destroy tap device from bridge
    return :  0 for success; -1 for failed
    '''      
    def destroyTapDev(self, tap, vnet):
        cmd = "ifconfig " + tap
	#if os.system(cmd) > 0:
        if commands.getstatusoutput(cmd)[0] > 0:
            return VMCErr
        cmd = "ifconfig " + tap + " down"
        os.system(cmd)
        cmd = "brctl delif " + vnet[0:13] + " " + tap
        os.system(cmd)
        cmd = "openvpn --rmtun --dev " + tap
        if commands.getstatusoutput(cmd)[0] == 0:
           return 0
        else:
           return VMCErr


    '''
    fuction:  destroy tap device from bridge
    return :  0 for success; -1 for failed
    '''      
    def destroyTap(self, tap, vnet):
        cmd = "ifconfig " + tap
	#if os.system(cmd) > 0:
        if commands.getstatusoutput(cmd)[0] > 0:
            return VMCErr
        cmd = "ifconfig " + tap + " down"
        os.system(cmd)
        cmd = "brctl delif " + vnet[0:13] + " " + tap
        os.system(cmd)
        cmd = "tunctl -d " + tap
        if commands.getstatusoutput(cmd)[0] == 0:
           return 0
        else:
           return VMCErr
       
    def vmc_strerror(self,errno):
        if errno == SaveFileErr:
            return "Failed to create configure file";
        
        if errno == DownLoadCertErr:
            return "Failed to download CA cert, client cert and client key";
        
        if errno == VSWConfNotExistErr:
            return "VSwitch configure file not exists";
        
        if errno == LibvirtOffErr:
            return "Failed to open connection to the hypervisor";
        
        if errno == VPNConfNotExistErr:
            return "VPN configure file not exists";
        
        if errno == CreateNetXMLErr:
            return "Failed to create network xml file";
        
        if errno == IfconfigUPErr:
            return "Failed to ifconfig up";
        
        if errno == VSwitchOffErr:
            return "Network don't exist";
        
        if errno == IfconfigDownErr:
            return "Failed to ifconfig down";
        
        if errno == OtherException:
            return "Other Exception throw";
        
        if errno == DestroyVSwitchErr:
            return "Failed to destroy vswitch";
        
        if errno == ParseConfErr:
            return "Failed to parse configure file";
        
        if errno == StartVSwitchErr:
            return "Failed to start vswitch";
        
        if errno == CreateVMErr:
            return "Failed to create vm";
        
        if errno == ShutdownVMErr:
            return "Failed to shutdown vm";
        
        if errno == UUIDNullErr:
            return "UUID is Null";
        
        if errno == DownloadRFSErr:
            return "Failed to download root file system";
        
        if errno == CreateVMImgErr:
            return "Failed to create vm image";
        
        if errno == VMImgNotExistErr:
            return "VM image not exist";
        
        if errno == RemoveVMDirErr:
            return "Failed to remove vm directory";
        
        if errno == VMCErr:
            return "VMC Error";    
 
    

